package cc.chengheng.filter;

import cc.chengheng.model.UserDTO;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Base64;
import java.util.Iterator;
import java.util.Map;

public class TokenAuthenticationFilter extends OncePerRequestFilter {

    /**
     * 微服务接收到令牌，解析令牌的代码
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 解析头中的token
        String token = request.getHeader("json‐token");
        if (token == null) {
            return;
        }

        byte[] decode = Base64.getDecoder().decode(token);
        String json = new String(decode, 0, decode.length);
        JsonNode jsonNode = new ObjectMapper().readTree(json);

        // 用户身份信息
        UserDTO userDTO = new UserDTO();
        String principal = jsonNode.get("principal").asText();
        userDTO.setUsername(principal);

        JsonNode authorities = jsonNode.get("authorities");
        Iterator<JsonNode> elements = authorities.getElements();

        String[] authoritiesStr = new String[100];

        // 将用户信息和权限填充到用户身份token对象中
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                = new UsernamePasswordAuthenticationToken(userDTO,
                null, AuthorityUtils.createAuthorityList(authoritiesStr));

        usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource()
                .buildDetails(request));

        // 将AuthenticationToken设置到安全上下文中
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        filterChain.doFilter(request, response);
    }
}
